package com.hopes.bizz.poll.job;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.StopWatch;
import com.hopes.bizz.common.core.util.CollectionUtils;
import com.hopes.bizz.poll.common.constant.MonitorConstant;
import com.hopes.bizz.poll.common.constant.OmConstant;
import com.hopes.bizz.poll.monitor.service.PollMonitorSiteService;
import com.hopes.bizz.poll.om.entity.BaseOmDataEntity;
import com.hopes.bizz.poll.om.entity.PollRtDataEntity;
import com.hopes.bizz.poll.om.service.PollRtDataService;
import com.hopes.bizz.poll.town.entity.BaseTownOmDataEntity;
import com.hopes.bizz.poll.town.entity.PollTownRtDataEntity;
import com.hopes.bizz.poll.town.handler.PollHisDataFactory;
import com.hopes.bizz.poll.town.handler.PollTownDataCalculate;
import com.hopes.bizz.poll.town.handler.PollTownDataTimeParser;
import com.hopes.bizz.poll.town.handler.PollTownHisDataFactory;
import com.hopes.bizz.poll.town.service.PollTownRtDataService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lyb
 * @version 1.0
 * @description: 统计乡镇数据平均值
 * @date 2023/9/27 10:17
 */

@Service
@Slf4j
public class CalculateTownDataService {

    @Resource
    private PollMonitorSiteService pollMonitorSiteService;

    @Resource
    private PollHisDataFactory pollHisDataFactory;

    @Resource
    private PollTownHisDataFactory pollTownHisDataFactory;

    @Resource
    private PollRtDataService pollRtDataService;

    @Resource
    private PollTownRtDataService pollTownRtDataService;

    private static final String HIS_KEY_PREFIX = "POLL:TOWN:HIS:";

    @Resource
    private RedisTemplate<String, Date> redisTemplate;

    @XxlJob("calculateTownDataHandler")
    public void calculateTownDataHandler() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        handler();
        stopWatch.stop();
        log.info("计算乡镇空气环境数据完成,耗时:{} 毫秒", stopWatch.getTotalTimeMillis());
        XxlJobHelper.handleSuccess();
    }

    private void handler() {
        // 查询所有空气站监控点
        List<Long> monitorSite = pollMonitorSiteService.getIdByMonitorMainType(MonitorConstant.MONITOR_TYPE_AIR);
        // 计算乡镇实时平均数据
        calculateRtData(monitorSite);
        // 计算乡镇历史平均数据
        calculateHisData(monitorSite);
    }

    private void calculateRtData(List<Long> monitorSite) {
        for (Integer dataType : OmConstant.DATA_TYPE_ARRAY) {
            PollTownDataTimeParser rtTimeParser = new PollTownDataTimeParser(dataType);
            rtTimeParser.parserRtd();
            Date beginTime = rtTimeParser.getBeginTime();
            Date endTime = rtTimeParser.getEndTime();
            List<PollRtDataEntity> list = pollRtDataService.lambdaQuery()
                    .in(PollRtDataEntity::getMonitorSiteId, monitorSite)
                    .eq(PollRtDataEntity::getDataType, dataType)
                    .ge(PollRtDataEntity::getDataTime, beginTime)
                    .le(PollRtDataEntity::getDataTime, endTime)
                    .list();
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
            // 统计
            PollTownDataCalculate pollTownDataCalculate = new PollTownDataCalculate(list);
            List<BaseTownOmDataEntity> townDataList = pollTownDataCalculate.calculate();
            List<PollTownRtDataEntity> dataList = townDataList.stream().map(data -> {
                PollTownRtDataEntity dataEntity = BeanUtil.copyProperties(data, PollTownRtDataEntity.class);
                dataEntity.setDataType(dataType);
                dataEntity.setDataTime(endTime);
                return dataEntity;
            }).collect(Collectors.toList());
            // 删除 保存
            List<Long> townIdList = dataList.stream().map(PollTownRtDataEntity::getTownId).collect(Collectors.toList());
            pollTownRtDataService.deleteByTownIdAndDataType(townIdList, dataType);
            pollTownRtDataService.saveBatch(dataList);
        }

    }

    private void calculateHisData(List<Long> monitorSite) {
        for (Integer dataType : OmConstant.DATA_TYPE_ARRAY) {
            PollTownDataTimeParser rtHisTimeParser = new PollTownDataTimeParser(dataType);
            rtHisTimeParser.parserHis();
            Date beginTime = rtHisTimeParser.getBeginTime();
            Date endTime = rtHisTimeParser.getEndTime();

            String key = HIS_KEY_PREFIX + dataType;

            Date date = redisTemplate.opsForValue().get(key);
            if (Objects.nonNull(date) && DateUtil.compare(date, endTime) <= 0) {
                continue;
            }

            List<? extends BaseOmDataEntity> list = pollHisDataFactory.getPollService(dataType).lambdaQuery()
                    .in(BaseOmDataEntity::getMonitorSiteId, monitorSite)
                    .gt(BaseOmDataEntity::getDataTime, beginTime)
                    .le(BaseOmDataEntity::getDataTime, endTime)
                    .orderByDesc(BaseOmDataEntity::getDataTime)
                    .list();
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
            PollTownDataCalculate pollTownDataCalculate = new PollTownDataCalculate(list);
            List<BaseTownOmDataEntity> townOmDataList = pollTownDataCalculate.calculate();
            townOmDataList.forEach(data -> data.setDataTime(endTime));
            // 保存结果
            pollTownHisDataFactory.getTownPollService(dataType).batchSaveData(townOmDataList);
            // 更新缓存
            redisTemplate.opsForValue().set(key, endTime);
        }
    }
}
